/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package coalescent.nb.jobs.properties;

import coalescent.nb.jobs.properties.editors.PhylogenyAlgorithmPropertyEditor;
import coalescent.nb.jobs.properties.editors.PropertyEditors;
import coalescent.phylogeny.CheckPPhylogenyAlgo;
import commons.nb.jobs.properties.BuilderProperty;
import commons.nb.jobs.properties.CommonsPropertySets;
import commons.nb.jobs.properties.Property;
import commons.nb.jobs.properties.Propertys;
import commons.nb.jobs.properties.editors.ValidatingInplaceEditor;
import commons.nb.jobs.properties.editors.ValidatingStringInplaceEditor;
import org.netbeans.validation.api.Validator;
import org.netbeans.validation.api.builtin.Validators;

import java.io.File;

/**
 * @author Susanta Tewari
 * @version 2.0.0
 * @history Created on April 15, 2011
 * @since 1.0.0
 */
public class CoalescentPropertys {

    /**
     * Private constructor to prevent instantiation.
     */
    private CoalescentPropertys() {}

    /**
     * Provides a property for valid double string as specified in {@link Double#parseDouble(java.lang.String)}.
     * Does not provide a property key, should be supplied by the client.
     *
     * @return a new instance of the property
     */
    public static Property<Double> THETA() {

        Property<Double> propimpl = Propertys.ofDouble();


        // descriptions
        propimpl.setName("theta");
        propimpl.setDisplayName("theta");
        propimpl.setShortDescription("Mutation rate");
        propimpl.setPropertySet(CommonsPropertySets.MODEL);


        // validator
        final Validator<String> validator = Validators.REQUIRE_VALID_NUMBER;

        propimpl.setValidator(validator);


        // inplace editor
        ValidatingInplaceEditor editor = new ValidatingStringInplaceEditor();

        editor.addValidator(validator);
        propimpl.getCustomParamValues().put("inplaceEditor", editor);


        // default value
        propimpl.setValue(1.0);

        return propimpl;
    }

    /**
     * Supplies the following property:
     * <ul>
     * <li>{@code coalescent.builder.StringKC64Data.cnForm = valid values are of the format f1^t1_f2^t2... where fi and ti are positive and represent the frequency domain, and the alleles on that frequency domain, respectively}</li>
     * </ul>
     *
     * @return a new instance of the property
     */
    public static Property<String> KC64_DATA() {

        Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("kc64Data");
        propimpl.setDisplayName("kc64Data");
        propimpl.setShortDescription("Infinite-Alleles Data");
        propimpl.setPropertySet(CommonsPropertySets.DATA);


        // validator
        final Validator<String> validator = Validators.regexp("(\\d+\\^\\d+_)*(\\d+\\^\\d+)",
                                                "It should be of the form f1^t1_f2^t2...", false);

        propimpl.setValidator(validator);


        // inplace editor
        ValidatingInplaceEditor editor = new ValidatingStringInplaceEditor();

        editor.addValidator(validator);
        propimpl.getCustomParamValues().put("inplaceEditor", editor);


        // key & value
        propimpl.setKey("coalescent.builder.StringKC64Data.cnForm");
        propimpl.setValue("1^3_2^1");

        return propimpl;
    }

    /**
     * Supplies the following property:
     * <ul>
     * <li>{@code coalescent.builder.CheckPPhylogenyAlgo.algorithm}("GUSFIELD", "FOURGAMETES")</li>
     * </ul>
     *
     * @return a new instance of the builder property
     */
    public static Property PHYLOGENY_ALGO() {

        CoalescentPropertyImpls.PhylogenyAlgorithmPropertyImpl propimpl =
            new CoalescentPropertyImpls.PhylogenyAlgorithmPropertyImpl();


        // descriptions & display category
        propimpl.setName("phylogeny-algorithm");
        propimpl.setDisplayName("phylogeny-algorithm");
        propimpl.setShortDescription("Phylogeny algorithm");
        propimpl.setPropertySet(CommonsPropertySets.ALGORITHMS);


        // validator
        propimpl.setPropEditorClass(PhylogenyAlgorithmPropertyEditor.class);


        // key & value
        propimpl.setKey("coalescent.builder.CheckPPhylogenyAlgo.algorithm");
        propimpl.setValue(CheckPPhylogenyAlgo.GUSFIELD);

        return propimpl;
    }

    /**
     * Supplies the following property:
     * <ul>
     * <li>{@code coalescent.builder.StringK69Data.url = stringk69data:xml//URL}<a href="coalescent/cef/pui/pob/doc-files/k69data.xml.txt">file format</a>, must accompany the <a href="coalescent/cef/pui/pob/doc-files/k69data.xsd.txt">schema</a></li>
     * </ul>
     *
     * @return a new instance of the builder property
     */
    public static Property<File> K69_DATA_URL() {

        return Propertys.ofFile(
            "infinite-sites-data", "infinite-sites-data", "Infinite-Sites Data",
            CommonsPropertySets.DATA, "coalescent.builder.K69Data.url", "k69:xml//",
            new File("C:/wspaces/coalescent/coalescent_rb_1.3/data/hein_k69_data.xml"));
    }

    /**
     * Supplies the following property:
     * <ul>
     * <li>{@code coalescent.builder.BRComputations.exactProb = true | false}</li>
     * </ul>
     *
     * @return a new instance of the builder property
     */
    public static Property<Boolean> RECURSION_COMPUTATION_EXACT_PROB() {

        final Property<Boolean> propimpl = Propertys.ofBoolean();


        // descriptions & display category
        propimpl.setName("compute-probability");
        propimpl.setDisplayName("compute probability?");
        propimpl.setShortDescription("Compute the exact probability");
        propimpl.setPropertySet(CommonsPropertySets.COMPUTATIONS);


        // key & value
        propimpl.setKey("coalescent.builder.BRComputations.exactProb");
        propimpl.setValue(true);

        return propimpl;
    }

    /**
     * Supplies the following property:
     * <ul>
     * <li>{@code coalescent.builder.BRComputations.configCounter = true | false}</li>
     * </ul>
     *
     * @return a new instance of the builder property
     */
    public static Property<Boolean> RECURSION_COMPUTATION_CONFIG_COUNT() {

        final Property<Boolean> propimpl = Propertys.ofBoolean();


        // descriptions & display category
        propimpl.setName("compute-config-count");
        propimpl.setDisplayName("compute config count?");
        propimpl.setShortDescription("Compute the total number of ancestral configurations");
        propimpl.setPropertySet(CommonsPropertySets.COMPUTATIONS);


        // key & value
        propimpl.setKey("coalescent.builder.BRComputations.configCounter");
        propimpl.setValue(true);

        return propimpl;
    }

    /**
     * Supplies the following property:
     * <ul>
     * <li>{@code coalescent.builder.BRComputations.genealogyCounter = true | false}</li>
     * </ul>
     *
     * @return a new instance of the builder property
     */
    public static Property<Boolean> RECURSION_COMPUTATION_GENEALOGY_COUNT() {

        final Property<Boolean> propimpl = Propertys.ofBoolean();


        // descriptions & display category
        propimpl.setName("compute-genealogy-count");
        propimpl.setDisplayName("count genealogies?");
        propimpl.setShortDescription("Compute the total number of genealogies");
        propimpl.setPropertySet(CommonsPropertySets.COMPUTATIONS);


        // key & value
        propimpl.setKey("coalescent.builder.BRComputations.genealogyCounter");
        propimpl.setValue(true);

        return propimpl;
    }

    /**
     * Supplies the following property:
     * <ul>
     * <li>{@code coalescent.builder.BRComputations.configBuilder = true | false}</li>
     * </ul>
     *
     * @return a new instance of the builder property
     */
    public static Property<Boolean> RECURSION_COMPUTATION_CONFIG_BUILDER() {

        final Property<Boolean> propimpl = Propertys.ofBoolean();


        // descriptions & display category
        propimpl.setName("compute-config-builder");
        propimpl.setDisplayName("build configs?");
        propimpl.setShortDescription("Build the ancestral configurations");
        propimpl.setPropertySet(CommonsPropertySets.COMPUTATIONS);


        // key & value
        propimpl.setKey("coalescent.builder.BRComputations.configBuilder");
        propimpl.setValue(false);

        return propimpl;
    }

    /**
     * Supplies the following property:
     * <ul>
     * <li>{@code coalescent.builder.BRComputations.genealogyBuilder = true | false}</li>
     * </ul>
     *
     * @return a new instance of the builder property
     */
    public static Property<Boolean> RECURSION_COMPUTATION_GENEALOGY_BUILDER() {

        final Property<Boolean> propimpl = Propertys.ofBoolean();


        // descriptions & display category
        propimpl.setName("compute-genealogy-builder");
        propimpl.setDisplayName("build genealogies?");
        propimpl.setShortDescription("Build all genealogies");
        propimpl.setPropertySet(CommonsPropertySets.COMPUTATIONS);


        // key & value
        propimpl.setKey("coalescent.builder.BRComputations.genealogyBuilder");
        propimpl.setValue(false);

        return propimpl;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static BuilderProperty K69Data_BUILDERS() {

        BuilderProperty propImpl = Propertys.ofBuilder();

        propImpl.setName("K69Data-builders");
        propImpl.setDisplayName("K69 Data Sets");
        propImpl.setShortDescription("K69 Data Sets");
        propImpl.setPropertySet(CommonsPropertySets.DATA);


        // property editor
        propImpl.setPropEditorClass(PropertyEditors.StringK69DataBuilderPropertyEditor.class);

        return propImpl;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static BuilderProperty BinaryData_BUILDERS() {

        BuilderProperty propImpl = Propertys.ofBuilder();

        propImpl.setName("BinaryData-builders");
        propImpl.setDisplayName("Binary Data Sets");
        propImpl.setShortDescription("Binary Data Sets");
        propImpl.setPropertySet(CommonsPropertySets.DATA);


        // property editor
        propImpl
            .setPropEditorClass(commons.nb.data.gui.properties.editors.PropertyEditors
                .ByteArrayListBuilderPropertyEditor.class);

        return propImpl;
    }
}
